package com.question.dicegame;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class DiceGameBoard extends JPanel implements Runnable {

	// 게임 객체들이 사용할 이미지
	private Image[] playerImage;
	private Image mapImage;
	private Image diceImage;
	private Image itemImage;

	// 게임 객체 클래스
	private Dice dice;
	private Player player;
	private Computer computer;

	// 마우스를 눌렀을 때 위치를 저장하기 위한 변수
	private Point startPoint = null;
	private Point endPoint = null;
	// int[] : 셀위치 (x,y)
	// private int[][] player;

	private Font font;
	public int number = 0;
	private int flag = 0;
	private ArrayList<int[]> items;
	// 쓰레드와 게임의 시작, 종료를 관리하기 위한 변수
	Thread thread = new Thread(this);
	boolean running;
	private int count;
	private long speed = 1000;
	private long lastAnimatedTime;

	public DiceGameBoard() {
		try {
			URL url = getClass().getResource("map.jpg");
			Image originalImage = ImageIO.read(url);

			mapImage = originalImage.getScaledInstance(Constants.FRAME_WIDTH,
					Constants.FRAME_HEIGHT, Image.SCALE_SMOOTH);

			playerImage = new Image[2];
			for (int i = 0; i < playerImage.length; i++) {
				url = getClass().getResource("player" + i + ".png");
				originalImage = ImageIO.read(url);
				playerImage[i] = originalImage;
			}

			url = getClass().getResource("dice.png");
			originalImage = ImageIO.read(url);
			diceImage = originalImage;

			url = getClass().getResource("item.png");
			originalImage = ImageIO.read(url);
			itemImage = originalImage.getScaledInstance(Constants.CELL_WIDTH,
					Constants.CELL_HEIGHT, Image.SCALE_SMOOTH);

		} catch (Exception ex) {
		}

		setBackground(Color.black);
		setDoubleBuffered(true);

		// 게임 객체 생성
		items = new ArrayList<int[]>();
		player = new Player(playerImage[0], 5);
		computer = new Computer(playerImage[1], 5);
		dice = new Dice(diceImage, 6);
		font = new Font("나눔고딕코딩", Font.BOLD, 20);

		addMouseListener(screenMouseHandler);

		startGame();

	}

	private void startGame() {

		count = 0;

		if (items.size() > 0)
			items.removeAll(items);

		for (int i = 0; i < 99; i++) {
			int[] item = new int[2];
			item[0] = (int) (Math.random() * 10);
			item[1] = (int) (Math.random() * 10);
			items.add(i, item);
		}

		Thread thread = new Thread(this);
		thread.start();

	}

	// 화면의 갱신이 필요할 때 호출되는 메서드 -> 출력을 처리하는 메서드
	@Override
	public void paint(Graphics g) {
		// TODO Auto-generated method stub
		super.paint(g);

		Graphics2D g2d = (Graphics2D) g;

		Image image = null;
		image = mapImage;
		g2d.drawImage(image, 0, 0, Constants.FRAME_WIDTH,
				Constants.FRAME_HEIGHT, this);

		player.draw(g2d, number, flag);
		computer.draw(g2d, number, flag);
		dice.draw(g2d, number);

		for (int i = 0; i < items.size(); i++) {
			int[] obj = items.get(i);
			g2d.drawImage(itemImage, obj[0] * Constants.CELL_WIDTH, obj[1]
					* Constants.CELL_HEIGHT, Constants.CELL_WIDTH,
					Constants.CELL_HEIGHT, this);
		}

		g2d.setFont(font);
		g2d.setColor(Color.gray);
		g2d.drawString("SCORE : " + count, 800, 80);

		g2d.setFont(font);
		g2d.setColor(Color.ORANGE);

		if (flag == 0) {
			g2d.drawString("플레이어 턴", 800, 20);
		} else {
			g2d.drawString("컴퓨터 턴", 800, 20);
		}

		if (!running) {
			if(flag == 0){
			g2d.setFont(new Font("나눔고딕코딩", Font.BOLD, 30));
			Rectangle2D r = g2d.getFontMetrics().getStringBounds("아쉽습니다~!" ,
					g2d);
			g2d.setColor(Color.BLACK);
			g2d.drawString("아쉽습니다~!",
					(Constants.FRAME_WIDTH - (int) r.getWidth()) / 2,
					(Constants.FRAME_HEIGHT - (int) r.getHeight()) / 2);
			r = g2d.getFontMetrics().getStringBounds("컴퓨터에게 패배하셨습니다!",
					g2d);
			g2d.setColor(Color.BLACK);
			g2d.drawString("컴퓨터에게 패배하셨습니다!",
					(Constants.FRAME_WIDTH - (int) r.getWidth()) / 2,
					(Constants.FRAME_HEIGHT - (int) r.getHeight()) / 2+50);
			r = g2d.getFontMetrics().getStringBounds("최종 스코어 : " +count,
					g2d);
			g2d.setColor(Color.BLACK);
			g2d.drawString("최종 스코어 : " +count,
					(Constants.FRAME_WIDTH - (int) r.getWidth()) / 2,
					(Constants.FRAME_HEIGHT - (int) r.getHeight()) / 2+100);
			}else{
				g2d.setFont(new Font("나눔고딕코딩", Font.BOLD, 30));
				Rectangle2D r = g2d.getFontMetrics().getStringBounds("축하드립니다~!!",
						g2d);
				g2d.setColor(Color.BLACK);
				g2d.drawString("축하드립니다~!!",
						(Constants.FRAME_WIDTH - (int) r.getWidth()) / 2,
						(Constants.FRAME_HEIGHT - (int) r.getHeight()) / 2);
				g2d.setFont(new Font("나눔고딕코딩", Font.BOLD, 30));
				r = g2d.getFontMetrics().getStringBounds("플레이어가 승리하셨습니다!!",
						g2d);
				g2d.setColor(Color.BLACK);
				g2d.drawString("플레이어가 승리하셨습니다!!",
						(Constants.FRAME_WIDTH - (int) r.getWidth()) / 2,
						(Constants.FRAME_HEIGHT - (int) r.getHeight()) / 2+50);
				g2d.setFont(new Font("나눔고딕코딩", Font.BOLD, 30));
				r = g2d.getFontMetrics().getStringBounds("최종 스코어 : "+count,
						g2d);
				g2d.setColor(Color.BLACK);
				g2d.drawString("최종 스코어 : "+count,
						(Constants.FRAME_WIDTH - (int) r.getWidth()) / 2,
						(Constants.FRAME_HEIGHT - (int) r.getHeight()) / 2+100);
			}
		}
	}

	@Override
	public void run() {
		running = true;

		while (running) {
			if (!running) {
				repaint();
				break;
			}
			int a = 0, b = -1;
			if (number != 0) {
				if (flag == 0) {
					for (int i = 0; i < number * 8; i++) {
						a = player.movePaint(number, a);
						repaint();
						try {
							Thread.sleep(30);
						} catch (Exception ex) {
						}
						b++;
						if (a == 1) {
							System.out.print(a);
							break;
						}
					}
					if (a == 1) {
						for (int i = 0; i < (number * 8)-b; i++) {
							System.out.print(b);
							player.backPaint();
							repaint();
							try {
								Thread.sleep(30);
							} catch (Exception ex) {
							}
						}
					}
					itemEvent();
					running = player.moveEvent();
					itemEvent();
					flag = 1;
					number = 0;
					lastAnimatedTime = System.currentTimeMillis();
				} else if (flag == 1) {
					for (int i = 0; i < (number) * 8; i++) {
						a = computer.movePaint(number,a);
						repaint();
						try {
							Thread.sleep(30);
						} catch (Exception ex) {
						}
						b++;
						if (a == 1) {
							System.out.print(a);
							break;
						}
					}
					if (a == 1) {
						for (int i = 0; i < (number * 8)-b; i++) {
							System.out.print(b);
							computer.backPaint();
							repaint();
							try {
								Thread.sleep(30);
							} catch (Exception ex) {
							}
						}
					}
					itemEvent();
					running = computer.moveEvent();
					itemEvent();
					flag = 0;
					number = 0;
				}
			}

			// 컴퓨터 프로세스
			if (flag == 1) {
				long current = System.currentTimeMillis();
				if (current - lastAnimatedTime > speed) {
					lastAnimatedTime = current;
					number = (int) ((Math.random() * 6) + 1);
					System.out.println("컴퓨터 : " + number);
				}
			}
			// draw
			repaint();
			try {
				Thread.sleep(30);
			} catch (Exception ex) {
			}

		}
	}

	private MouseAdapter screenMouseHandler = new MouseAdapter() {
		@Override
		public void mousePressed(MouseEvent e) {
			startPoint = e.getPoint();
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			endPoint = e.getPoint();

			if (startPoint.x >= 840 && startPoint.x <= 920
					&& startPoint.y >= 560 && startPoint.y <= 640
					&& endPoint.x >= 840 && endPoint.x <= 920
					&& endPoint.y >= 560 && endPoint.y <= 640 && flag == 0) {
				if (number != 0) {
					return;
				}
				 number = (int) ((Math.random() * 6) + 1);
				//number = 6;
				System.out.println("플레이어 :" + number);
			}
			startPoint = null;
			endPoint = null;
		}
	};

	public void itemEvent() {
		for (int i = 0; i < items.size(); i++) {
			if ((player.getX() == items.get(i)[0] * 80 && player.getY() == items
					.get(i)[1] * 80)
					|| (computer.getX() == items.get(i)[0] * 80 && computer
							.getY() == items.get(i)[1] * 80)) {
				if (flag == 0)
					count += 100;

				items.remove(items.get(i));
			}
		}
	}
}
